#include <iostream>

// 策略模式

class CashSuper
{
private:
    /* data */
public:
    virtual double acceptCash(double money) = 0;
};

class CashNoraml : public CashSuper
{

public:
    virtual double acceptCash(double money)
    {
        return money;
    }
};

class CashRebate : public CashSuper
{

public:
    void rebate(double money)
    {
        this->_money = money;
    }

    virtual double acceptCash(double money)
    {
        return _money * money;
    }

private:
    double _money = 2.5;
};

// 传入不同策略对象
class CashContext
{
public:
    // 方式-
    CashContext(CashSuper *cashSuper)
    {
        this->_pCashSuper = cashSuper;
    }

    // 方式二
    CashContext(int type)
    {
        switch (type)
        {
        case 1:
            this->_pCashSuper = new CashNoraml;
            break;
        default:
            this->_pCashSuper = new CashRebate;
            break;
        }
    }

    double accept(double money)
    {
        return this->_pCashSuper->acceptCash(money);
    }

    ~CashContext()
    {
        if (this->_pCashSuper != NULL)
        {
            delete this->_pCashSuper;
        }
    }

private:
    CashSuper *_pCashSuper = NULL;
};

template <class T>
class Strategy
{
private:
    T _c;

public:
    Strategy(/* args */) {}
    ~Strategy() {}
    double accept(double money)
    {
        return _c.acceptCash(money);
    }
};

int main(int argc, char const *argv[])
{
    /* code */
    CashContext ctx = new CashNoraml;
    std::cout << ctx.accept(100.0) << "\n";
    CashContext *ctx1 = new CashContext(new CashRebate);
    std::cout << ctx1->accept(100.2) << "\n";

    CashContext ctx2 = 1;
    std::cout << ctx2.accept(300.2) << "\n";

    Strategy<CashNoraml> s0;
    std::cout << s0.accept(10000.78) << "\n";
    return 0;
}
